
/*
 *
 *  * Copyright (c) 2016. For Intelligent Group.
 *
 */

package com.intelligent.ispc.client.ex.dynamictable;

import com.google.common.collect.Lists;

import java.util.List;

/**
 * Created by Peter on 2016/10/22.
 */
public class DyTableLoader {
    public static final int ROW = 0;
    public static final int COL = 1;
    private int flag = ROW;

    private DyTableModel dyTableModel;
    private int fixedColSize = 0;

    private DyTableModel fixedModel;
    private DyTableModel normalModel;

    private int pageSize;
    private int pageNumber = 1;
    private DyLoadTask task;
    private int pageCount = 1;
    private int mod = 0;

    /**
     * Constructor.
     *
     * @param dyTableModel dyTableModel
     * @param fixedColSize fixedColSize
     * @param pageSize     pageSize
     * @param flag         ROW/COL
     * @param task         DyLoadTask instance.
     */
    public DyTableLoader(DyTableModel dyTableModel, int fixedColSize, int pageSize, int flag, DyLoadTask task) {
        this.dyTableModel = dyTableModel;
        this.pageSize = pageSize;
        this.fixedColSize = fixedColSize;
        this.task = task;
        this.flag = flag;

        initDataSource();
    }

    /**
     * Initialize the number of pages
     *
     * @param count The count of the total data
     */
    public void initPageCount(int count) {
        mod = count % pageSize;
        if (mod == 0) {
            this.pageCount = count / pageSize;
        } else {
            this.pageCount = (count / pageSize) + 1;
        }

    }

    /**
     * Initialize the load data, define fixedModel and normalModel
     */
    public void initBatch() {
        this.pageNumber = 1;
        dyTableModel.setData(task.load(0, pageSize));

        if (fixedColSize > 0 && fixedModel == null) {
            fixedModel = new DyAbstractTableModel() {
                public int getColumnCount() {
                    return fixedColSize;
                }

                public int getRowCount() {
                    return dyTableModel.getRowCount();
                }

                public String getColumnName(int col) {
                    return (String) dyTableModel.getColumnName(col);
                }

                public Object getValueAt(int row, int col) {
                    return dyTableModel.getValueAt(row, col);
                }

                @Override
                public List getData() {
                    return dyTableModel.getData();
                }

                @Override
                public void setData(List data) {
                    dyTableModel.setData(data);
                }
            };
        }
        if (normalModel == null) {
            normalModel = new DyAbstractTableModel() {
                private static final long serialVersionUID = 1L;

                public int getColumnCount() {
                    return dyTableModel.getColumnCount() - fixedColSize;
                }

                public int getRowCount() {
                    return dyTableModel.getData().size();
                }

                public String getColumnName(int col) {
                    return (String) dyTableModel.getColumnName(col + fixedColSize);
                }

                public Object getValueAt(int row, int col) {
                    return dyTableModel.getValueAt(row, col + fixedColSize);
                }

                public void setValueAt(Object obj, int row, int col) {
                    dyTableModel.setValueAt(obj, row, col + fixedColSize);
                }

                @Override
                public List getData() {
                    return dyTableModel.getData();
                }

                @Override
                public void setData(List data) {
                    dyTableModel.setData(data);
                }
            };
        }
    }

    /**
     * Reset the parameter properties
     */
    public void resetProperties() {
        pageNumber = 1;
        pageCount = 1;
        mod = 0;

        if (dyTableModel != null) {
            dyTableModel.setData(Lists.newArrayList());
            ((DyAbstractTableModel) dyTableModel).fireTableStructureChanged();
        }

        if (normalModel != null) {
            normalModel.setData(Lists.newArrayList());
            ((DyAbstractTableModel) normalModel).fireTableStructureChanged();
        }

        if (fixedModel != null) {
            fixedModel.setData(null);
            ((DyAbstractTableModel) fixedModel).fireTableStructureChanged();
        }
    }

    /**
     * Execute the next batch
     */
    public void nextBatch() {
        if (flag == ROW) {
            nextRowPage();
        } else {
            nextColPage();
        }
        ((DyAbstractTableModel) normalModel).fireTableStructureChanged();
    }

    /**
     * Execute the Previous batch
     */
    public void preBatch() {
        if (flag == ROW) {
            preRowPage();
        } else {
            preColPage();
        }
        ((DyAbstractTableModel) normalModel).fireTableStructureChanged();
    }

    /*
    Initialize the data source
     */
    private void initDataSource() {
        if (dyTableModel.getData() == null) {
            dyTableModel.setData(Lists.newArrayList());
        }
    }

    /*
    Load a vertical scroll bar on the next page
     */
    private void nextRowPage() {
        List list = dyTableModel.getData();

        if (pageNumber > 1) {
            list.removeAll(list.subList(0, pageSize));
        }

        List newList = task.load(pageNumber * pageSize, (pageNumber + 1) * pageSize);
        list.addAll(newList);

        dyTableModel.setData(list);

        pageNumber++;
    }

    /*
    Load a Horizontal scroll bar on the next page
     */
    private void nextColPage() {
        List list = dyTableModel.getData();
        list.clear();

        List newList;
        //Judge whether the data of the last page is smaller than the pageSize
        if (pageNumber == (pageCount - 1) && mod != 0) {
            newList = task.load((pageNumber - 1) * pageSize, (pageNumber + 1) * pageSize);
        } else {
            newList = task.load(pageNumber * pageSize, (pageNumber + 1) * pageSize);
        }
        dyTableModel.setData(newList);

        pageNumber++;

    }

    /*
    Load a vertical scroll bar on the previous page
     */
    private void preRowPage() {
        if (pageNumber == 1) {
            return;
        }
        List list = dyTableModel.getData();
        List newList = Lists.newArrayList();
        int initPage = 3;
        if (pageNumber >= initPage) {
            newList = task.load((pageNumber - initPage) * pageSize, (pageNumber - 2) * pageSize);
        }

        if (pageNumber > 1) {
            list.removeAll(list.subList(pageSize, list.size()));
        }

        newList.addAll(list);
        dyTableModel.setData(newList);

        pageNumber--;
        if (pageNumber < 1) {
            pageNumber = 1;
        }
    }

    /*
   Load a Horizontal scroll bar on the previous page
    */
    private void preColPage() {
        if (pageNumber == 1) {
            return;
        }

        List list = dyTableModel.getData();
        list.clear();

        List newList = task.load((pageNumber - 2) * pageSize, (pageNumber - 1) * pageSize);
        dyTableModel.setData(newList);

        pageNumber--;
        if (pageNumber < 1) {
            pageNumber = 1;
        }
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public DyLoadTask getTask() {
        return task;
    }

    public void setTask(DyLoadTask task) {
        this.task = task;
    }

    public DyTableModel getDyTableModel() {
        return dyTableModel;
    }

    public void setDyTableModel(DyTableModel dyTableModel) {
        this.dyTableModel = dyTableModel;
    }

    public int getFixedColSize() {
        return fixedColSize;
    }

    public void setFixedColSize(int fixedColSize) {
        this.fixedColSize = fixedColSize;

    }

    public DyTableModel getFixedModel() {
        return fixedModel;
    }

    public void setFixedModel(DyTableModel fixedModel) {
        this.fixedModel = fixedModel;
    }

    public DyTableModel getNormalModel() {
        return normalModel;
    }

    public void setNormalModel(DyTableModel normalModel) {
        this.normalModel = normalModel;
    }

    public int getFlag() {
        return flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    public int getPageCount() {
        return pageCount;
    }

}
